package com.crane.oss.school.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.crane.common.core.dto.SingleResponse;
import com.crane.common.core.utils.CollectionUtil;
import com.crane.common.framework.utils.DateUtil;
import com.crane.common.framework.utils.Jackson2JsonUtil;
import com.crane.oss.app.bean.req.AppAddTaskReq;
import com.crane.oss.app.bean.req.AppCommitCommentReq;
import com.crane.oss.app.bean.req.AppDelCommentReq;
import com.crane.oss.app.bean.req.AppQueryTaskRopeDayDetailReq;
import com.crane.oss.app.bean.resp.*;
import com.crane.oss.app.dao.AppUserDao;
import com.crane.oss.app.model.AppUser;
import com.crane.oss.enums.GradeEnum;
import com.crane.oss.school.bean.request.task.*;
import com.crane.oss.school.bean.resp.*;
import com.crane.oss.school.dao.*;
import com.crane.oss.school.model.*;
import com.crane.oss.school.service.TaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: zx
 * @Date: 2023/01/23/19:46
 * @Description:
 */
@Service
@Slf4j
public class TaskServiceImpl implements TaskService {

    @Resource
    TaskDao taskDao;
    @Resource
    TaskTimeDao taskTimeDao;
    @Resource
    TaskStudentDao taskStudentDao;
    @Resource
    TeacherDao teacherDao;
    @Resource
    TaskImageDao taskImageDao;
    @Resource
    StudentClassDao studentClassDao;
    @Resource
    ClassesInfoDao classesInfoDao;
    @Resource
    AreaDao areaDao;
    @Resource
    StudentDao studentDao;
    @Resource
    StudentSkipropeDao studentSkipropeDao;
    @Resource
    AppUserDao appUserDao;
    @Resource
    StudentEquipmentDao studentEquipmentDao;
    @Resource
    EquipmentDao equipmentDao;

    @Override
    public Map<String, List<TaskRopeWebResp>> queryTaskRopeList(QueryTaskRopeListReq req) {
        if(CollectionUtils.isEmpty(req.getClassIds())){
            List<ClassesInfo> classesInfoList = classesInfoDao.selectList(Wrappers.lambdaQuery(ClassesInfo.class)
                    .eq(null != req.getSchoolId(),ClassesInfo ::getSchoolId ,req.getSchoolId())
                    .eq(null != req.getGrade(),ClassesInfo ::getGrade,req.getGrade())
                    .eq(null != req.getType(),ClassesInfo ::getType,req.getType()));
            if(!CollectionUtils.isEmpty(classesInfoList)){
                req.setClassIds(classesInfoList.stream().map(ClassesInfo ::getClassId).collect(Collectors.toList()));
            }
        }
        if(CollectionUtils.isEmpty(req.getClassIds())){
            return new HashMap<>();
        }
        IPage<TaskRopeWebResp> page = taskDao.queryTaskRopeWebResp(new Page<>(req.getPageNo(), req.getPageSize()), req);
        if (CollectionUtils.isEmpty(page.getRecords())) {
            return new HashMap<>();
        }
        List<Long> classIds = page.getRecords().stream().map(TaskRopeWebResp::getClassId).distinct().collect(Collectors.toList());
        List<StudentClass> studentClassList = studentClassDao.selectList(Wrappers.lambdaQuery(StudentClass.class).in(StudentClass::getClassId, classIds));
        Map<Long, Long> counts = studentClassList.stream().collect(Collectors.groupingBy(StudentClass::getClassId, Collectors.counting()));
        page.getRecords().forEach(o -> {
            o.setStudentCount(counts.get(o.getClassId()).intValue());
        });
        Map<Date, List<TaskRopeWebResp>> resps = page.getRecords().stream().collect(Collectors.groupingBy(TaskRopeWebResp::getRuleTime));
        Map<String, List<TaskRopeWebResp>> result=new TreeMap<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o2.compareTo(o1);
            }
        });
        resps.forEach((key,value)->{
            result.put(DateUtil.format(DateUtil.DATE_PATTERN,key),value);
        });
        return result;
    }

    @Override
    public TaskResp queryTaskDetail(Long taskId) {
        TaskResp taskResp = new TaskResp();
        Task task = taskDao.selectById(taskId);
        if (null == task) {
            return null;
        }
        BeanUtils.copyProperties(task, taskResp);
        Teacher teacher = teacherDao.selectById(task.getCreateUserId());
        taskResp.setCreateUserName(teacher.getName());

        List<TaskImage> imageList = taskImageDao.selectList(Wrappers.lambdaQuery(TaskImage.class).eq(TaskImage::getTaskId, task.getTaskId()));
        if (!CollectionUtils.isEmpty(imageList)) {
            taskResp.setImages(imageList.stream().map(TaskImage::getUrl).collect(Collectors.toList()));
        }
        ClassesInfo classesInfo = classesInfoDao.selectById(task.getClassId());
        Area area = areaDao.selectById(classesInfo.getSchoolId());
        taskResp.setClassAllName(area.getAreaName() + GradeEnum.getGradeEnum(classesInfo.getGrade()) + classesInfo.getClassName());
        return taskResp;
    }

    @Override
    public IPage<TaskRopeStudentResp> queryTaskDetailRopeList(QueryTaskDetailRopeListReq request) {
        return taskDao.queryTaskDetailRopeList(new Page<>(request.getPageNo(), request.getPageSize()), request);
    }

    @Override
    public TotalSkipRopeResp queryTotalSkipRope(Long studentId) {
        QueryStudentTaskDetailListReq req = new QueryStudentTaskDetailListReq();
        req.setStartTime(Date.from(LocalDateTime.of(LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()), LocalTime.MIN).atZone(ZoneId.systemDefault()).toInstant()));
        req.setEndTime(Date.from(LocalDateTime.of(LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()), LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant()));
        req.setStudentId(studentId);
        TotalSkipRopeResp totalSkipRopeResp= taskDao.queryTotalSkipRope(req);
        Student student=studentDao.selectById(studentId);
        if(null == totalSkipRopeResp){
            totalSkipRopeResp =new TotalSkipRopeResp();
        }
        totalSkipRopeResp.setName(student.getName());
        totalSkipRopeResp.setHeadUrl(student.getImg());
        totalSkipRopeResp.setAvgFrequency(new BigDecimal(totalSkipRopeResp.getSkipPopeCount()).multiply(new BigDecimal(60)).divide(new BigDecimal(totalSkipRopeResp.getDurationCount()),2, RoundingMode.HALF_UP).doubleValue());
        return totalSkipRopeResp;
    }

    @Override
    public IPage<TaskStudentSkipRopeResp> queryStudentTaskDetailList(QueryStudentTaskDetailListReq request) {
        request.setStartTime(Date.from(LocalDateTime.of(LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()), LocalTime.MIN).atZone(ZoneId.systemDefault()).toInstant()));
        request.setEndTime(Date.from(LocalDateTime.of(LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()), LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant()));
        return taskDao.queryStudentTaskDetailList(new Page<>(request.getPageNo(), request.getPageSize()), request);
    }

    @Override
    public IPage<AppTeacherSkipRopeResp> queryTeacherSkipRopeList(QueryTaskRopeListReq req) {
        IPage<AppTeacherSkipRopeResp> page = taskDao.queryTeacherSkipRopeList(new Page<>(req.getPageNo(), req.getPageSize()), req);
        if (CollectionUtils.isEmpty(page.getRecords())) {
            return page;
        }
        List<Long> classIds = page.getRecords().stream().map(AppTeacherSkipRopeResp::getClassId).distinct().collect(Collectors.toList());
        List<StudentClass> studentClassList = studentClassDao.selectList(Wrappers.lambdaQuery(StudentClass.class).in(StudentClass::getClassId, classIds));
        if (!CollectionUtils.isEmpty(studentClassList)) {
            Map<Long, Long> counts = studentClassList.stream().collect(Collectors.groupingBy(StudentClass::getClassId, Collectors.counting()));
            page.getRecords().forEach(o -> {
                if (null != counts.get(o.getClassId())) {
                    o.setStudentCount(counts.get(o.getClassId()).intValue());
                } else {
                    o.setStudentCount(0);
                }
                o.setClassAllName(o.getSchoolName() + "|" + GradeEnum.getGradeEnum(o.getGrade()) + "|" + o.getClassAllName());
            });
        }
        return page;
    }

    @Override
    public TaskTeacherSkipPopeResp queryTeacherSkipRopeDetail(Long taskId, Long partyId) {
        TaskTeacherSkipPopeResp taskResp = new TaskTeacherSkipPopeResp();
        Task task = taskDao.selectById(taskId);
        if (null == task) {
            return null;
        }
        BeanUtils.copyProperties(task, taskResp);
        List<TaskImage> imageList = taskImageDao.selectList(Wrappers.lambdaQuery(TaskImage.class).eq(TaskImage::getTaskId, task.getTaskId()));
        if (!CollectionUtils.isEmpty(imageList)) {
            taskResp.setImages(imageList.stream().map(TaskImage::getUrl).collect(Collectors.toList()));
        }
        ClassesInfo classesInfo = classesInfoDao.selectById(task.getClassId());
        Area area = areaDao.selectById(classesInfo.getSchoolId());
        taskResp.setClassAllName(area.getAreaName() + GradeEnum.getGradeEnum(classesInfo.getGrade()) + classesInfo.getClassName());
        //查询打卡日期
        List<TaskTime> taskTimes = taskTimeDao.selectList(Wrappers.lambdaQuery(TaskTime.class).eq(TaskTime::getTaskId, taskId));
        taskResp.setRuleTimes(taskTimes.stream().map(TaskTime::getRuleTime).collect(Collectors.toList()));
        return taskResp;
    }

    @Override
    public TaskSkipPopeDayDetailResp queryTeacherSkipRopeDayDetail(AppQueryTaskRopeDayDetailReq req) {
        TaskSkipPopeDayDetailResp taskSkipPopeDayDetailResp = new TaskSkipPopeDayDetailResp();
        Task task = taskDao.selectById(req.getTaskId());
        if (null == task) {
            return null;
        }
        //查询班级所有学生
        Map<String, Object> map = new HashMap<>();
        map.put("classId", task.getClassId());
        List<TaskStudentSkipRopeResp> committed = new ArrayList<>();
        List<String> unCommitted = new ArrayList<>();
        taskSkipPopeDayDetailResp.setCommitted(committed);
        taskSkipPopeDayDetailResp.setUnCommitted(unCommitted);
        List<StudentWebDto> queryList = studentDao.queryList(map);
        List<TaskStudentSkipRopeResp> taskStudentList = taskStudentDao.queryTaskStudentSkipRope(req.getTaskId(), null, DateUtil.format(DateUtil.DATE_PATTERN,req.getFinishTime()));
        taskStudentList=taskStudentList.stream().filter(o-> null != o.getFinishTime()).collect(Collectors.toList());
        for (StudentWebDto studentWebDto : queryList) {
            boolean commit = false;
            for (TaskStudentSkipRopeResp taskStudent : taskStudentList) {
                if (taskStudent.getStudentId().equals(studentWebDto.getStudentId())) {
                    TaskStudentSkipRopeResp studentSkipRopeResp = new TaskStudentSkipRopeResp();
                    BeanUtils.copyProperties(taskStudent, studentSkipRopeResp);
                    studentSkipRopeResp.setStudentName(studentWebDto.getName());
                    committed.add(studentSkipRopeResp);
                    commit = true;
                    break;
                }
            }
            if (!commit) {
                unCommitted.add(studentWebDto.getName());
            }
        }
        return taskSkipPopeDayDetailResp;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean commitComment(AppCommitCommentReq req) {
        List<TaskStudent> taskStudentList = taskStudentDao.selectList(Wrappers.lambdaQuery(TaskStudent.class).in(TaskStudent::getId, req.getStudentTaskIds()));
        if (!CollectionUtils.isEmpty(taskStudentList)) {
            for (TaskStudent taskStudent : taskStudentList) {
                taskStudent.setStars(req.getStar());
                taskStudent.setTaskComment(req.getTeacherComment());
                taskStudent.setReviewerId(req.getOpUserId());
                taskStudent.setReviewerTime(new Date());
                taskStudentDao.updateById(taskStudent);
            }
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean delComment(AppDelCommentReq req) {
        TaskStudent taskStudent = taskStudentDao.selectById(req.getStudentTaskId());
        taskStudent.setStars(0);
        taskStudent.setTaskComment("");
        taskStudent.setReviewerTime(null);
        taskStudentDao.updateById(taskStudent);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean delTask(Long taskId, Long partyId) {
        Task task = taskDao.selectById(taskId);
        if (null == task) {
            return false;
        }
        taskDao.deleteById(taskId);
        taskTimeDao.delete(Wrappers.lambdaQuery(TaskTime.class).eq(TaskTime::getTaskId, taskId));
        taskImageDao.delete(Wrappers.lambdaQuery(TaskImage.class).eq(TaskImage::getTaskId, taskId));
        taskStudentDao.delete(Wrappers.lambdaQuery(TaskStudent.class).eq(TaskStudent::getTaskId, taskId));
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addTask(AppAddTaskReq request) {
        Task task = new Task();
        task.setTitle(request.getTitle());
        task.setDescribes(request.getDescribes());
        task.setClassId(request.getClassId());
        task.setType(1);
        task.setSubType(request.getSubType());
        task.setStartTime(request.getStartTime());
        task.setEndTime(request.getEndTime());
        task.setState(0);
        task.setRuleJson(Jackson2JsonUtil.toString(request.getRuleJson()));
        task.setAfterClock(request.getAfterClock());
        task.setCreateTime(new Date());
        task.setCreateUserId(request.getOpUserId());
        taskDao.insert(task);

        if (!CollectionUtils.isEmpty(request.getImages())) {
            for (String url : request.getImages()) {
                TaskImage taskImage = new TaskImage();
                taskImage.setTaskId(task.getTaskId());
                taskImage.setUrl(url);
                taskImageDao.insert(taskImage);
            }
        }
        //计算日期
        if (request.getRuleJson().getType() == 1) {
            TaskTime taskTime = new TaskTime();
            taskTime.setTaskId(task.getTaskId());
            taskTime.setRuleTime(request.getStartTime());
            taskTime.setFinishCount(0);
            taskTimeDao.insert(taskTime);
        } else if (request.getRuleJson().getType() == 2) {
            Calendar ca = Calendar.getInstance();
            ca.setTime(request.getStartTime());
            while (ca.getTime().before(request.getEndTime())) {
                int week=ca.get(Calendar.DAY_OF_WEEK) -1 ;
                if(week== 0){
                    week =7;
                }
                if (week <6 ) {
                    TaskTime taskTime = new TaskTime();
                    taskTime.setTaskId(task.getTaskId());
                    taskTime.setRuleTime(ca.getTime());
                    taskTime.setFinishCount(0);
                    taskTimeDao.insert(taskTime);
                }
                ca.add(Calendar.DAY_OF_MONTH, 1);
            }
        } else if (request.getRuleJson().getType() == 3) {
            Calendar ca = Calendar.getInstance();
            ca.setTime(request.getStartTime());
            while (ca.getTime().before(request.getEndTime())) {
                int week=ca.get(Calendar.DAY_OF_WEEK) -1 ;
                if(week== 0){
                    week =7;
                }
                if (request.getRuleJson().getWeek().contains(week)) {
                    TaskTime taskTime = new TaskTime();
                    taskTime.setTaskId(task.getTaskId());
                    taskTime.setRuleTime(ca.getTime());
                    taskTime.setFinishCount(0);
                    taskTimeDao.insert(taskTime);
                }
                ca.add(Calendar.DAY_OF_MONTH, 1);
            }
        }
        return true;
    }

    @Override
    public IPage<AppStudentSkipRopeResp> queryTaskRopeStudentList(QueryStudentTaskRopeListReq request) {
        List<StudentClass> queryList = studentClassDao.selectList(Wrappers.lambdaQuery(StudentClass.class)
                .eq(StudentClass::getStudentId, request.getStudentId())
                .eq(StudentClass::getDelFlag, 0));
        if (CollectionUtil.isEmpty(queryList)) {
            return new Page<>();
        }
        request.setClassIds(queryList.stream().map(StudentClass::getClassId).collect(Collectors.toList()));
        return taskDao.queryTaskRopeStudentList(new Page<>(request.getPageNo(), request.getPageSize()), request);
    }

    @Override
    public TaskStudentSkipPopeResp queryStudentSkipRopeDetail(Long taskId, Long studentId) {
        TaskStudentSkipPopeResp taskResp = new TaskStudentSkipPopeResp();
        Task task = taskDao.selectById(taskId);
        if (null == task) {
            return null;
        }
        BeanUtils.copyProperties(task, taskResp);
        //查询打卡日期
        List<TaskTime> taskTimes = taskTimeDao.selectList(Wrappers.lambdaQuery(TaskTime.class).eq(TaskTime::getTaskId, taskId));
        taskResp.setRuleTimes(taskTimes.stream().map(TaskTime::getRuleTime).collect(Collectors.toList()));

        List<TaskImage> imageList = taskImageDao.selectList(Wrappers.lambdaQuery(TaskImage.class).eq(TaskImage::getTaskId, task.getTaskId()));
        if (!CollectionUtils.isEmpty(imageList)) {
            taskResp.setImages(imageList.stream().map(TaskImage::getUrl).collect(Collectors.toList()));
        }
        List<TaskStudentSkipRopeResp> list = taskStudentDao.queryTaskStudentSkipRope(taskId, studentId, null);
        list=list.stream().filter(o-> null != o.getFinishTime()).collect(Collectors.toList());
        taskResp.setTotalDays(taskTimes.size());
        taskResp.setCommitDays(list.size());
//        if (!CollectionUtils.isEmpty(list)) {
//            List<TaskStudentSkipPopeListResp> skipPopeList = new ArrayList<>();
//            taskResp.setSkipPopeList(skipPopeList);
//            for (TaskStudentSkipRopeResp taskStudentSkipRopeResp : list) {
//                TaskStudentSkipPopeListResp taskStudentSkipPopeListResp = new TaskStudentSkipPopeListResp();
//                BeanUtils.copyProperties(taskStudentSkipRopeResp, taskStudentSkipPopeListResp);
//                skipPopeList.add(taskStudentSkipPopeListResp);
//            }
//        }
        AppUser appUser = appUserDao.selectOne(Wrappers.lambdaQuery(AppUser.class).eq(AppUser::getAppUserId, task.getCreateUserId()));
        taskResp.setHeadUrl(appUser.getHeadUrl());
        Teacher teacher = teacherDao.selectOne(Wrappers.lambdaQuery(Teacher.class).eq(Teacher::getAppUserId, task.getCreateUserId()));
        taskResp.setTeacherName(teacher.getName());


        return taskResp;
    }

    @Override
    public SingleResponse<TaskStudentSkipRopeResp> queryStudentSkipRopeDayDetail(AppQueryTaskRopeDayDetailReq request) {
        List<TaskStudentSkipRopeResp> list = taskStudentDao.queryTaskStudentSkipRope(request.getTaskId(), request.getStudentId(), DateUtil.format(DateUtil.DATE_PATTERN,request.getFinishTime()));
        if (!CollectionUtils.isEmpty(list)) {
            return SingleResponse.of(list.get(0));
        }
        return SingleResponse.buildSuccess();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public SingleResponse<Long> addTaskRopeReq(AddTaskRopeReq request) {
        Task task = taskDao.selectById(request.getTaskId());
        if (null == task) {
            return SingleResponse.buildFailure("未绑定任务");
        }
        //查询设备绑定的用户
        StudentEquipment studentEquipment=studentEquipmentDao.selectOne(Wrappers.lambdaQuery(StudentEquipment.class)
                .eq(StudentEquipment ::getEquipmentId,request.getEquipmentId())
                .eq(StudentEquipment ::getBindStatus,1));
        if (null == studentEquipment) {
            return SingleResponse.buildFailure("设备未绑定学生");
        }
        request.setStudentId(studentEquipment.getStudentId());
        Equipment equipment=equipmentDao.selectOne(Wrappers.lambdaQuery(Equipment.class).eq(Equipment ::getEquipmentId,request.getEquipmentId()));
        if(null == equipment || equipment.getStatus().equals(2)){
            return SingleResponse.buildFailure("设备不可用");
        }
        LocalDateTime ldt = LocalDateTime.of(new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(), LocalTime.MIN);
        Date mini = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
        Integer timeOut = 0;
        if (request.getRuleTime().after(mini)) {
            timeOut = 1;
            if (task.getAfterClock().equals(0)) {
                return SingleResponse.buildFailure("超时不能打卡");
            }
        }
        StudentSkiprope studentSkiprope = new StudentSkiprope();
        studentSkiprope.setStudentId(request.getStudentId());
        studentSkiprope.setEquipmentId(request.getEquipmentId());
        studentSkiprope.setQuantity(0);
        studentSkiprope.setFrequency(0.00);
        studentSkiprope.setKcal(0.0D);
        studentSkiprope.setBeginTime(new Date());
        studentSkiprope.setStatus(1);
        studentSkiprope.setDuration(0);
        studentSkiprope.setType(1);
        studentSkiprope.setModel(equipment.getSkipmode());
        studentSkiprope.setCreateTime(new Date());
        studentSkipropeDao.insert(studentSkiprope);

        List<TaskStudentSkipRopeResp> list = taskStudentDao.queryTaskStudentSkipRope(request.getTaskId(), request.getStudentId(), DateUtil.format(DateUtil.DATE_PATTERN,request.getRuleTime()));
        if (!CollectionUtils.isEmpty(list)) {
            TaskStudentSkipRopeResp taskStudentSkipRopeResp = list.get(0);
            taskStudentDao.deleteById(taskStudentSkipRopeResp.getStudentTaskId());
        }
        TaskStudent taskStudent = new TaskStudent();
        taskStudent.setTaskId(request.getTaskId());
        taskStudent.setStudentId(request.getStudentId());
        taskStudent.setStars(0);
        taskStudent.setRelationId(studentSkiprope.getSkipId());
        taskStudent.setRuleTime(request.getRuleTime());
        taskStudent.setTimeOut(timeOut);
        taskStudentDao.insert(taskStudent);
        return SingleResponse.of(taskStudent.getId());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public SingleResponse<Boolean> endTaskRopeReq(EndTaskRopeReq request) {
        //查询设备绑定的用户
        StudentEquipment studentEquipment=studentEquipmentDao.selectOne(Wrappers.lambdaQuery(StudentEquipment.class)
                .eq(StudentEquipment ::getEquipmentId,request.getEquipmentId())
                .eq(StudentEquipment ::getBindStatus,1));
        if (null == studentEquipment) {
            return SingleResponse.buildFailure("设备未绑定学生");
        }
        request.setStudentId(studentEquipment.getStudentId());
        Equipment equipment=equipmentDao.selectOne(Wrappers.lambdaQuery(Equipment.class).eq(Equipment ::getEquipmentId,request.getEquipmentId()));
        if(null == equipment || equipment.getStatus().equals(2)){
            return SingleResponse.buildFailure("设备不可用");
        }
        request.setModel(request.getModel());
        if (null != request.getTaskId()) {
            List<TaskStudentSkipRopeResp> list = taskStudentDao.queryTaskStudentSkipRope(request.getTaskId(), request.getStudentId(), DateUtil.format(DateUtil.DATE_PATTERN,request.getRuleTime()));
            if (CollectionUtils.isEmpty(list)) {
                return SingleResponse.buildFailure("无开始打卡记录");
            }
            TaskStudentSkipRopeResp taskStudentSkipRopeResp = list.get(0);
            TaskStudent taskStudent=taskStudentDao.selectById(taskStudentSkipRopeResp.getStudentTaskId());
            taskStudent.setFinishTime(new Date());
            taskStudentDao.updateById(taskStudent);

            StudentSkiprope studentSkiprope = studentSkipropeDao.selectById(taskStudentSkipRopeResp.getSkipId());
            BeanUtils.copyProperties(request, studentSkiprope);
            studentSkiprope.setStatus(2);
            studentSkipropeDao.updateById(studentSkiprope);
        }
        return SingleResponse.of(true);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void compluteTaskSkip() {
        List<TaskTimeResp> taskTimeResps = taskTimeDao.compluteskip();
        for (TaskTimeResp taskTimeResp : taskTimeResps) {
            TaskTime taskTime = taskTimeDao.selectOne(Wrappers.lambdaQuery(TaskTime.class).eq(TaskTime::getTaskId, taskTimeResp.getTaskId())
                    .eq(TaskTime::getRuleTime, taskTimeResp.getRuleTime()));
            if (null != taskTime) {
                taskTime.setFinishCount(taskTimeResp.getFinishCount());
            }
            TaskStudentSkipRopeResp taskStudentSkipRopeResp = taskStudentDao.queryGoodStudent(taskTimeResp.getTaskId());
            if (null != taskStudentSkipRopeResp) {
                taskTime.setGoodStudentId(taskStudentSkipRopeResp.getStudentId());
            }
            taskTimeDao.updateById(taskTime);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void compluteTaskState() {
        List<Task> tasks = taskDao.selectList(Wrappers.lambdaQuery(Task.class).in(Task::getState, Arrays.asList(0, 1)));
        for (Task task : tasks) {
            if (task.getStartTime().before(new Date())) {
                task.setState(1);
            }
            if (task.getEndTime().before(new Date())) {
                task.setState(2);
            }
            taskDao.updateById(task);
        }
    }


}
